package controller

import (
	"background/config"
	"background/db"
	"background/logs"
	"background/model"
	"time"

	"fmt"
	"strconv"
	"strings"
	"sync"

	"github.com/gin-gonic/gin"
	"github.com/olivere/elastic/v7"
	"qiniupkg.com/x/log.v7"
)

type DocTree struct {
	ID       int64      `json:"id"`
	Label    string     `json:"label"`
	Level    int        `json:"level"`
	Children []*DocTree `json:"children"`
}

var gDocMapCache map[int]*DocTree = nil
var gLock sync.Mutex

func init() {
	if nil == gDocMapCache {
		gDocMapCache = make(map[int]*DocTree)
	}
}

func InitDocCache() {
	gLock.Lock()
	for k := range gDocMapCache {
		delete(gDocMapCache, k)
	}

	articles := []model.Doc{}
	e := db.GetMysqlClient().Query2("select id,title,father,level from doc_copy1 where father != 2500", &articles)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	for _, v := range articles {
		tmp := new(DocTree)
		tmp.ID = v.ID
		tmp.Level = int(v.Level)
		tmp.Label = v.Title
		tmp.Children = make([]*DocTree, 0)
		gDocMapCache[int(v.ID)] = tmp
	}
	for _, v := range articles {
		tmp := new(DocTree)
		tmp.ID = v.ID
		tmp.Label = v.Title
		tmp.Level = int(v.Level)
		tmp.Children = make([]*DocTree, 0)
		gDocMapCache[int(v.ID)] = tmp
	}
	for _, v := range articles {
		if v.Father != 0 {
			if gDocMapCache[int(v.Father)] != nil {
				gDocMapCache[int(v.Father)].Children = append(gDocMapCache[int(v.Father)].Children, gDocMapCache[int(v.ID)])
			} else {
				log.Print(v.Father)
			}
		}
	}

	gLock.Unlock()
	log.Print(gDocMapCache)

}

func GetPageParaFromQuery(c *gin.Context) (int, int) {
	limit := c.Query("limit")
	offset := c.Query("offset")

	iLmit, e := strconv.Atoi(limit)
	if nil != e {
		return 0, 0
	}
	iOffset, e := strconv.Atoi(offset)
	if nil != e {
		return 0, 0
	}
	return iLmit, iOffset
}

func GetArticlesTree(c *gin.Context) {
	rsp := RespBase{"ERR", -1, nil}
	defer func() {
		c.JSON(200, rsp)
	}()
	articles := []model.Doc{}
	e := db.GetMysqlClient().Query2("select id,title,father,level from doc_copy1  where father != 2500", &articles)
	if nil != e {
		logs.Error(e.Error())
		return
	}

	InitDocCache()
	ret := []*DocTree{}
	for _, v := range articles {
		if v.Level == 0 {
			ret = append(ret, gDocMapCache[int(v.ID)])
		}
	}

	rsp.Data = ret
	rsp.Msg = "OK"
	rsp.Status = 0
}

func GetArticles(c *gin.Context) {
	type ReqArticles struct {
		Name string `json:"name"`
		Type int32  `json:"types"`
	}
	var req ReqArticles
	rsp := RespBase{"ERR", -1, nil}
	defer func() {
		c.JSON(200, rsp)
	}()
	e := c.BindJSON(&req)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	article := []model.Doc{}
	limit, offset := GetPageParaFromQuery(c)
	public := c.Query("is_public")

	var sql string
	if req.Name != "" {
		if req.Type == 110 {
			is_public := 0
			if public == "true" {
				is_public = 1
			} else {
				is_public = 0
			}
			sql = "select * from doc where doc.title like '%%%s%%' and is_public = %d limit %d offset %d "
			sql = fmt.Sprintf(sql, req.Name, is_public, limit, offset*limit)
		} else {
			is_public := 0
			if public == "true" {
				is_public = 1
			} else {
				is_public = 0
			}
			sql = fmt.Sprintf("select * from doc where doc.title  like '%%%s%%' and doc.type = %d and is_public = %d limit %d offset %d ",
				req.Name, req.Type, is_public, limit, offset*limit)
		}
	} else {
		if req.Type == 110 {
			is_public := 0
			if public == "true" {
				is_public = 1
			} else {
				is_public = 0
			}
			sql = fmt.Sprintf("SELECT doc.id,doc.author,LEFT(doc.content,50) as content,doc.title,doc.type from doc where is_public = %d "+
				"order by id desc limit %d offset %d", is_public, limit, offset)
		} else {
			is_public := 0
			if public == "true" {
				is_public = 1
			} else {
				is_public = 0
			}
			sql = fmt.Sprintf("SELECT doc.id,doc.author,LEFT(doc.content,50) as content,doc.title,doc.type from doc where doc.type = %d and is_public = %d "+
				" order by id desc limit %d offset %d", req.Type, is_public, limit, offset)

		}
	}
	log.Print(sql)
	e = db.GetMysqlClient().Query2(sql, &article)
	if nil != e {
		logs.Error(e.Error(), sql)
		return
	}
	for k, _ := range article {
		article[k].Content += "..."
	}
	rsp.Data = article

	rsp.Status = 0
	rsp.Msg = "OK"
}

func GetArticleCount(c *gin.Context) {
	resp := RespBase{Msg: "FAIL", Status: 211}

	defer func() {
		c.JSON(200, resp)
	}()

	query := fmt.Sprintf("select count(*) as cnt from doc")
	type Cnt struct {
		Cnt int64 `sql:"cnt" json:"cnt"`
	}
	cnt := []Cnt{}

	e := db.GetMysqlClient().Query2(query, &cnt)
	if nil != e {
		log.Print(e.Error())
		return
	}
	resp.Data = cnt[0]
	resp.Status = 0
	resp.Msg = "OK"
}

// InsertDocHistory

func AddArticleHistory(c *gin.Context) {
	rsp := RespBase{Msg: "FAIL", Status: 211}
	type ReqUpdateArticle struct {
		ID       int64  `json:"id"`
		Title    string `json:"title"`
		Content  string `json:"content"`
		Author   string `json:"author"`
		Type     int64  `json:"type"`
		IsPublic int    `json:"is_public"`
		Father   int    `json:"father"`
		Level    int    `json:"level"`
	}
	var req ReqUpdateArticle
	defer func() {
		c.JSON(200, rsp)
	}()

	er := c.BindJSON(&req)
	if nil != er {
		logs.Error(er.Error())
		return
	}
	if req.Title == "" {
		rsp.Msg = "title required"
		return
	}

	e := model.InsertDocHistory(model.DocTree{
		ID:      (req.ID),
		Type:    int32(req.Type),
		Title:   req.Title,
		Content: req.Content,
		Author:  req.Author,
		Father:  int32(req.Father),
		Level:   int32(req.Level),
	})
	if nil != e {
		logs.Error(er.Error())
		return
	}
	rsp.Msg = "OK"
	rsp.Status = 0

}
func GetArticleHistory(c *gin.Context) {
	resp := RespBase{Msg: "FAIL", Status: 211}
	defer func() {
		c.JSON(200, resp)
	}()

	sid := c.Query("id")
	log.Print(sid)
	query := `select * from doc_history where doc_id=` + sid
	log.Print(query)
	doc_history := []model.DocHistory{}

	e := db.GetMysqlClient().Query2(query, &doc_history)
	if nil != e {
		log.Print(e.Error())
		return
	}
	resp.Data = doc_history
	resp.Status = 0
	resp.Msg = "OK"
}

func GetArticle(c *gin.Context) {

	resp := RespBase{Msg: "FAIL", Status: 211}
	sid := c.Param("id")
	var id int
	var err error

	defer func() {
		c.JSON(200, resp)
	}()

	if sid == "" {
		return
	} else {
		id, err = strconv.Atoi(sid)
		if nil != err {
			return
		}
	}
	query := fmt.Sprintf("select * from doc_copy1 where doc_copy1.id = '%d'", id)
	docs := []model.Doc{}
	e := db.GetMysqlClient().Query2(query, &docs)
	fmt.Print(query, docs)

	if nil != e {
		log.Print(e.Error())
		return
	}
	if len(docs) > 0 {
		docs[0].Content = strings.ReplaceAll(docs[0].Content, `https://www.testingcloud.club/sapi/api/image_download`, `https://python.hdrtc.net:9443/down_img`)
		resp.Data = docs[0]
		resp.Status = 0
		resp.Msg = "OK"
	}

}

func UpdateArtilce(c *gin.Context) {
	rsp := RespBase{Msg: "FAIL", Status: 210}
	type ReqUpdateArticle struct {
		ID       int64  `json:"id"`
		Title    string `json:"title"`
		Content  string `json:"content"`
		Author   string `json:"author"`
		Type     int64  `json:"type"`
		IsPublic int    `json:"is_public"`
	}
	var req ReqUpdateArticle
	defer func() {
		c.JSON(200, rsp)
	}()

	er := c.BindJSON(&req)
	if nil != er {
		logs.Error(er.Error())
		return
	}
	if req.Title == "" {
		rsp.Msg = "title required"
		return
	}
	query := fmt.Sprintf("select * from doc where doc.id = '%d'", req.ID)
	docs := []model.Doc{}
	e := db.GetMysqlClient().Query2(query, &docs)
	if nil != e {
		log.Print(e.Error())
		return
	}
	if len(docs) == 0 {
		rsp.Msg = "不存在该"
		return
	}
	e = model.UpdateDoc(
		model.Doc{
			Type:     int32(req.Type),
			Title:    req.Title,
			Content:  req.Content,
			Author:   req.Author,
			ID:       req.ID,
			IsPublic: int32(req.IsPublic),
			Version:  (docs[0].Version + 1),
		},
	)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	rsp.Msg = "OK"
	rsp.Status = 0

}

func UpdateArtilceTree(c *gin.Context) {
	rsp := RespBase{Msg: "FAIL", Status: 210}
	type ReqUpdateArticle struct {
		ID       int64  `json:"id"`
		Title    string `json:"title"`
		Content  string `json:"content"`
		Author   string `json:"author"`
		Type     int64  `json:"type"`
		IsPublic int    `json:"is_public"`
		Father   int    `json:"father"`
		Level    int    `json:"level"`
	}
	var req ReqUpdateArticle
	defer func() {
		c.JSON(200, rsp)
	}()

	er := c.BindJSON(&req)
	if nil != er {
		logs.Error(er.Error())
		return
	}
	if req.Title == "" {
		rsp.Msg = "title required"
		return
	}
	query := fmt.Sprintf("select * from doc_copy1 where doc_copy1.id = '%d'", req.ID)
	docs := []model.Doc{}
	e := db.GetMysqlClient().Query2(query, &docs)
	if nil != e {
		log.Print(e.Error())
		return
	}
	if len(docs) == 0 {
		rsp.Msg = "不存在该"
		return
	}
	log.Print(req.Content)
	req.Content = strings.ReplaceAll(req.Content, "\\", "\\\\")
	e = model.UpdateDocTree(
		model.DocTree{
			Type:     int32(req.Type),
			Title:    req.Title,
			Content:  req.Content,
			Author:   req.Author,
			ID:       req.ID,
			IsPublic: int32(req.IsPublic),
			Version:  (docs[0].Version + 1),
			Father:   int32(req.Father),
			Level:    int32(req.Level),
		},
	)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	rsp.Msg = "OK"
	rsp.Status = 0
	config.RedisOne().Del("artilcetree")

}

func SearchArticleESHightLight(c *gin.Context) {
	type RetHighlight struct {
		ID        int64    `json:"id" gorm:"column:id" sql:"id"`
		Title     string   `json:"title" gorm:"column:title" sql:"title"`
		Type      int32    `json:"type" gorm:"column:type" sql:"type"`
		Highlight []string `json:"highlight" gorm:"column:highlight" sql:"highlight"`
	}
	rsp := RespBase{Msg: "FAIL", Status: 210}
	defer func() {
		c.JSON(200, rsp)
	}()
	type Req struct {
		Term string `json:"term"`
	}
	var req Req
	e := c.BindJSON(&req)
	if nil != e {
		log.Print(e.Error())
		return
	}

	query := elastic.NewMatchQuery("content", req.Term)
	highlight := elastic.NewHighlight()
	highlight = highlight.Fields(elastic.NewHighlighterField("content"))
	highlight = highlight.PreTags("<span>").PostTags("</span>")
	x := []RetHighlight{}
	_, e = db.GetElastic().
		QueryHighlight("doc", query, &x, highlight, 10, 0)
	if nil != e {
		log.Print(e.Error())
		return
	}

	rsp.Data = x
	rsp.Msg = "OK"
	rsp.Status = 0
}

func SearchArticleES(c *gin.Context) {
	rsp := RespBase{Msg: "FAIL", Status: 210}
	defer func() {
		c.JSON(200, rsp)
	}()
	type Req struct {
		Term string `json:"term"`
	}
	var req Req
	e := c.BindJSON(&req)
	if nil != e {
		log.Print(e.Error())
		return
	}

	query := elastic.NewTermQuery("content", req.Term)
	x := []model.Doc{}
	_, e = db.GetElastic().Query("doc", query, &x, 10, 0)
	if nil != e {
		log.Print(e.Error())
		return
	}
	rsp.Data = x
	rsp.Msg = "OK"
	rsp.Status = 0
}

func AddArticleTree(c *gin.Context) {
	rsp := RespBase{Msg: "FAIL", Status: 210}
	type ReqAddArticle struct {
		Title    string `json:"title"`
		Content  string `json:"content"`
		Author   string `json:"author"`
		Type     int64  `json:"type"`
		Ispublic int    `json:"is_public"`
		Father   int    `json:"father"`
		Level    int    `json:"level"`
	}
	var req ReqAddArticle
	defer func() {
		c.JSON(200, rsp)
	}()
	er := c.BindJSON(&req)
	if nil != er {
		logs.Error(er.Error())
		return
	}
	if req.Title == "" {
		rsp.Msg = "title required"
		return
	}
	log.Print(req.Level)

	content := strings.Replace(string(req.Content), "\\", "\\\\", -1)
	content = strings.Replace(content, "&gt", ">", -1)
	content = strings.Replace(content, "&lt", "<", -1)

	e := model.CreateDocTree(
		model.DocTree{
			Type:     int32(req.Type),
			Title:    req.Title,
			Content:  content,
			Author:   req.Author,
			IsPublic: int32(req.Ispublic),
			Father:   int32(req.Father),
			Level:    int32(req.Level),
		},
	)
	if nil != e {
		logs.Error(e.Error())
		return
	}

	query := fmt.Sprintf("select * from doc_copy1 where doc_copy1.title = '%s'", req.Title)
	docs := []model.DocTree{}
	e = db.GetMysqlClient().Query2(query, &docs)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	fmt.Print(query, docs)

	e = model.InsertCrawDocToElaticSearch(model.DocTree{
		ID:         docs[0].ID,
		Type:       int32(req.Type),
		Title:      req.Title,
		Content:    string(req.Content),
		Author:     req.Author,
		IsPublic:   int32(req.Ispublic),
		Father:     int32(req.Father),
		Level:      int32(req.Level),
		CreateTime: time.Now(),
		UpdateTime: time.Now(),
	})
	if nil != e {
		log.Print(e.Error())
	}
	config.RedisOne().Del("artilcetree")
	rsp.Msg = "OK"
	rsp.Status = 0
	rsp.Data = model.GetIdFromTitle(req.Title)
}

func AddKnowledge(c *gin.Context) {
	rsp := RespBase{Msg: "FAIL", Status: 210}
	type ReqAddArticle struct {
		Title    string `json:"title"`
		Content  string `json:"content"`
		Author   string `json:"author"`
		Type     int64  `json:"type"`
		Ispublic int    `json:"is_public"`
		Father   int    `json:"father"`
		Level    int    `json:"level"`
	}
	var req ReqAddArticle
	defer func() {
		c.JSON(200, rsp)
	}()
	er := c.BindJSON(&req)
	if nil != er {
		logs.Error(er.Error())
		return
	}
	if req.Title == "" {
		rsp.Msg = "title required"
		return
	}
	log.Print(req.Level)

	e := model.CreateCrawDoc(
		model.DocTree{
			Type:     int32(req.Type),
			Title:    req.Title,
			Content:  req.Content,
			Author:   req.Author,
			IsPublic: int32(req.Ispublic),
			Father:   int32(req.Father),
			Level:    int32(req.Level),
		},
	)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	rsp.Msg = "OK"
	rsp.Status = 0
}
func ArticlesType(c *gin.Context) {
	rsp := RespBase{Msg: "FAIL", Status: 210}
	defer func() {
		c.JSON(200, rsp)
	}()
	rsp.Data = model.GetArticlesType()
	rsp.Msg = "OK"
	rsp.Status = 0
}
func DeleteArticleType(c *gin.Context) {
	rsp := RespBase{Msg: "Fail", Status: 210}
	defer func() {
		c.JSON(200, rsp)
	}()

	sid := c.Query("id")
	if sid == "" {
		return
	}
	id, e := strconv.Atoi(sid)
	if nil != e {
		log.Print(e.Error())
		return
	}
	rsp.Data = model.DeleteArticleType(int32(id))
	rsp.Msg = "OK"
	rsp.Status = 0
}

func AddArticleType(c *gin.Context) {
	rsp := RespBase{Msg: "Fail", Status: 210}
	defer func() {
		c.JSON(200, rsp)
	}()

	typeName := c.Query("name")
	group := c.Query("group")
	groupid, e := strconv.Atoi(group)
	if nil != e {
		return
	}
	id := c.Query("id")
	if id != "" {
		if typeName == "" {
			return
		}
		articleType := model.ArticleType{
			Id:    0,
			Name:  typeName,
			Group: int32(groupid),
		}
		rsp.Data = model.UpdateArticleType(articleType)
		rsp.Msg = "OK"
		rsp.Status = 0
	} else {
		if typeName == "" {
			return
		}
		articleType := model.ArticleType{
			Id:    0,
			Name:  typeName,
			Group: int32(groupid),
		}
		rsp.Data = model.AddArticleType(articleType)
		rsp.Msg = "OK"
		rsp.Status = 0
	}
}

func DeleteArticle(c *gin.Context) {
	rsp := RespBase{Msg: "FAIL", Status: 210}
	defer func() {
		c.JSON(200, rsp)
	}()
	sid := c.Param("id")
	id, err := strconv.Atoi(sid)
	if nil != err {
		rsp.Status = -234
		c.JSON(200, rsp)
	}
	err = model.DeleteDoc(int64(id))
	if nil != err {
		rsp.Status = -234
		c.JSON(200, rsp)
	}
	rsp.Data = id
	rsp.Status = 0
	rsp.Msg = "OK"
}

func DeleteArticleTree(c *gin.Context) {
	rsp := RespBase{Msg: "FAIL", Status: 210}
	defer func() {
		c.JSON(200, rsp)
	}()
	sid := c.Param("id")
	id, err := strconv.Atoi(sid)
	if nil != err {
		rsp.Status = -234
		c.JSON(200, rsp)
	}
	err = model.DeleteDocTree(int64(id))
	if nil != err {
		rsp.Status = -234
		c.JSON(200, rsp)
	}
	config.RedisOne().Del("artilcetree")

	rsp.Data = id
	rsp.Status = 0
	rsp.Msg = "OK"
}

func ArticlesTypes(c *gin.Context) {
	resp := RespBase{"unkown error", -231, nil}
	defer func() {
		c.JSON(200, resp)
	}()

	docTypes := []model.ArticleType{}
	e := db.GetMysqlClient().Query2("select * from doc_type",
		&docTypes)
	if nil != e {
		log.Print(e.Error())
		return
	}
	resp.Data = docTypes
	resp.Msg = "OK"
	resp.Status = 0
}

func SearchArticles(c *gin.Context) {
	type ReqSearch struct {
		Term string `json:"term"`
	}
	resp := RespBase{"unkown error", -231, nil}
	defer func() {
		c.JSON(200, resp)
	}()

	docTypes := []model.Doc{}
	e := db.GetMysqlClient().Query2("select * from doc_type",
		&docTypes)
	if nil != e {
		log.Print(e.Error())
		return
	}
	resp.Data = docTypes
	resp.Msg = "OK"
	resp.Status = 0
}

func CreateMemo(c *gin.Context) {
	resp := RespBase{"unkown error", -231, nil}
	defer func() {
		c.JSON(200, resp)
	}()
	var req model.Memo
	e := c.BindJSON(&req)
	if nil != e {
		logs.Error(e.Error())
		resp.Msg = "wrong input"
		return
	}
	e = model.CreateMemo(req)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	resp.Data = nil
	resp.Msg = "OK"
	resp.Status = 0
}

func CreateBook(c *gin.Context) {
	resp := RespBase{"unkown error", -231, nil}
	defer func() {
		c.JSON(200, resp)
	}()
	var req model.Book
	e := c.BindJSON(&req)
	if nil != e {
		logs.Error(e.Error())
		resp.Msg = "wrong input"
		return
	}
	req.ID = 0
	e = db.GetOrm().Create(&req).Error
	if nil != e {
		logs.Error(e.Error())
		return
	}
	resp.Data = req
	resp.Msg = "OK"
	resp.Status = 0
}

func BookCount(c *gin.Context) {
	resp := RespBase{"unkown error", -231, nil}
	defer func() {
		c.JSON(200, resp)
	}()
	count := 0
	db.GetOrm().Model(&model.Book{}).Count(&count)
	resp.Data = count
	resp.Msg = "OK"
	resp.Status = 0
}

func Delbook(c *gin.Context) {
	type Req struct {
		ID int32 `json:"id"`
	}
	var req Req
	resp := RespBase{"unkown error", -231, nil}
	defer func() {
		c.JSON(200, resp)
	}()

	e := c.BindJSON(&req)
	if nil != e {
		logs.Error(e.Error())
		resp.Msg = "wrong input"
		return
	}
	count := 0
	e = db.GetOrm().Model(&model.Book{}).Delete(model.Book{ID: int64(req.ID)}).Error
	if nil != e {
		log.Printf(e.Error())
		return
	}
	resp.Data = count
	resp.Msg = "OK"
	resp.Status = 0
}

func UpdateBook(c *gin.Context) {
	resp := RespBase{"unkown error", -231, nil}
	defer func() {
		c.JSON(200, resp)
	}()
	var req model.Book
	e := c.BindJSON(&req)
	if nil != e {
		resp.Msg = "wrong input"
		log.Print(e.Error())
		return
	}
	e = db.GetOrm().Model(&model.Book{}).Update(&req).Error
	if nil != e {
		logs.Error(e.Error())
		return
	}
	resp.Data = nil
	resp.Msg = "OK"
	resp.Status = 0
}

func GetBook(c *gin.Context) {
	type ReqGetBook struct {
		ID int32 `json:"id"`
	}
	resp := RespBase{}
	var req ReqGetBook
	defer func() {
		c.JSON(200, resp)
	}()
	e := c.BindJSON(&req)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	var book model.Book
	book.ID = int64(req.ID)
	e = db.GetOrm().First(&book, req.ID).Error
	if e != nil {
		logs.Error(e.Error)
		return
	}
	resp.Data = book
	resp.Msg = "OK"
	resp.Status = 0
}

func GetPageBook(c *gin.Context) {
	type ReqGetPageBook struct {
		BookName string `json:"book_name"`
	}
	var req ReqGetPageBook
	resp := RespBase{}
	defer func() {
		c.JSON(200, resp)
	}()

	limit := c.Query("limit")
	offset := c.Query("offset")

	iLmit, e := strconv.Atoi(limit)
	if nil != e {
		log.Print(e.Error())
		return
	}
	iOffset, e := strconv.Atoi(offset)
	if nil != e {
		log.Print(e.Error())
		return
	}
	e = c.BindJSON(&req)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	books := []model.Book{}

	if req.BookName != "" {
		e = db.GetOrm().Model(&model.Book{}).
			Where(fmt.Sprintf("book_name like '%%%s%%' ", req.BookName)).
			Limit(iLmit).Offset(iOffset).Find(&books).Error
		if nil != e {
			log.Print(e.Error())
			return
		}
	} else {
		e = db.GetOrm().Model(&model.Book{}).
			Limit(iLmit).Offset(iOffset).Find(&books).Error
		if nil != e {
			log.Print(e.Error())
			return
		}
	}

	resp.Status = 0
	resp.Msg = "OK"
	resp.Data = books
}

func UpdateMemo(c *gin.Context) {
	resp := RespBase{"unkown error", -231, nil}
	defer func() {
		c.JSON(200, resp)
	}()
	var req model.Memo
	e := c.BindJSON(&req)
	if nil != e {
		resp.Msg = "wrong input"
		return
	}
	e = model.UpdateMemo(req)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	resp.Data = nil
	resp.Msg = "OK"
	resp.Status = 0
}

func GetDocTypeGroup(c *gin.Context) {
	type DocType struct {
		Id int32 `json:"id"`
	}
	rsp := RespBase{"ERR", -1, nil}
	defer func() {
		c.JSON(200, rsp)
	}()

	var id DocType
	e := c.BindJSON(&id)
	if nil != e {
		log.Print(e.Error)
		return
	}
	group, e := model.GetTypeGroup(id.Id)
	if nil != e {
		log.Print(e.Error)
		return
	}
	rsp.Data = group
	rsp.Status = 0
	rsp.Msg = "OK"
}

func GetDoGroupcType(c *gin.Context) {
	type DocType struct {
		Id int32 `json:"id"`
	}
	rsp := RespBase{"ERR", -1, nil}
	defer func() {
		c.JSON(200, rsp)
	}()

	var id DocType
	e := c.BindJSON(&id)
	if nil != e {
		log.Print(e.Error)
		return
	}
	group, e := model.GetGroupTypes(id.Id)
	if nil != e {
		log.Print(e.Error)
		return
	}
	rsp.Data = group
	rsp.Status = 0
	rsp.Msg = "OK"
}
func GetDocGroup(c *gin.Context) {
	rsp := RespBase{"ERR", -1, nil}
	defer func() {
		c.JSON(200, rsp)
	}()
	group, e := model.GetAllGroup()
	if nil != e {
		log.Print(e.Error())
		return
	}
	rsp.Data = group
	rsp.Status = 0
	rsp.Msg = "OK"
}

func GetTemplates(c *gin.Context) {
	rsp := RespBase{"ERR", -1, nil}
	defer func() {
		c.JSON(200, rsp)
	}()

}

func GetMemos(c *gin.Context) {
	rsp := RespBase{"ERR", -1, nil}
	defer func() {
		c.JSON(200, rsp)
	}()
	type ReqMemos struct {
		Title string `json:"title"`
	}
	req := ReqMemos{}
	e := c.BindJSON(&req)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	limit, offset := GetPageParaFromQuery(c)
	if limit != 0 && offset != 0 {
		dat, e := model.GetMemos(req.Title, limit, offset)
		if nil != e {
			return
		}
		rsp.Data = dat
		rsp.Status = 0
		rsp.Msg = "OK"
	} else {
		dat, e := model.GetMemos(req.Title, limit, offset)
		if nil != e {
			return
		}
		rsp.Data = dat
		rsp.Status = 0
		rsp.Msg = "OK"
	}

}

func GetMemoCnt(c *gin.Context) {
	rsp := RespBase{"ERR", -1, nil}
	defer func() {
		c.JSON(200, rsp)
	}()
	count := model.MemoCnt()

	rsp.Msg = "OK"
	rsp.Status = 0
	rsp.Data = count

}

func GetMemo(c *gin.Context) {
	rsp := RespBase{"ERR", -1, nil}
	defer func() {
		c.JSON(200, rsp)
	}()
	id := c.Query("id")
	dat, e := model.ReadMemo(int32(db.Atoi(id)))
	if nil != e {
		return
	}
	rsp.Msg = "OK"
	rsp.Status = 0
	rsp.Data = dat
}

func DeleteMemos(c *gin.Context) {
	resp := RespBase{"unkown error", -231, nil}
	defer func() {
		c.JSON(200, resp)
	}()
	type DelReq struct {
		Id int32 `json:"id"`
	}
	var req DelReq
	e := c.BindJSON(&req)
	if nil != e {
		resp.Msg = "wrong input"
		return
	}
	e = model.DeleteMemo(req.Id)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	resp.Data = nil
	resp.Msg = "OK"
	resp.Status = 0
}

func CreateDocTemplate(c *gin.Context) {
	resp := RespBase{}
	defer func() {
		c.JSON(200, resp)
	}()
	var req model.DocTemplate
	e := c.BindJSON(&req)
	if nil != e {
		logs.Error(e.Error())
		resp.Msg = "wrong input"
		return
	}
	e = model.CreateDocTemplate(req)
	if nil != e {
		log.Print(e.Error())
		return
	}
	resp.Data = nil
	resp.Msg = "OK"
	resp.Status = 0
}

func UpdateDocTemplate(c *gin.Context) {
	resp := RespBase{}
	defer func() {
		c.JSON(200, resp)
	}()
	var req model.DocTemplate
	e := c.BindJSON(&req)
	if nil != e {
		resp.Msg = "wrong input"
		return
	}
	e = model.UpdateDocTemplate(req)
	if nil != e {
		logs.Error(e.Error())
		return
	}
	resp.Data = nil
	resp.Msg = "OK"
	resp.Status = 0
}

func GetDocTemplate(c *gin.Context) {
	type ReqGet struct {
		Title string `json:"title"`
	}
	req := ReqGet{}
	resp := RespBase{}
	defer func() {
		c.JSON(200, resp)
	}()
	e := c.BindJSON(&req)
	if nil != e {
		log.Print(e.Error())
		return
	}
	ret, e := model.GetDocTemplate(req.Title, 5, 0)
	if nil != e {
		log.Print(e.Error())
		return
	}
	resp.Data = ret
	resp.Msg = "OK"
	resp.Status = 0
}

func DeleteDocTemplate(c *gin.Context) {
	resp := RespBase{}
	defer func() {
		c.JSON(200, resp)
	}()
	sid := c.Param("id")
	id, e := strconv.Atoi(sid)
	if nil != e {
		log.Print(e.Error())
		return
	}
	e = model.DeleteDocTemplate(int32(id))
	if nil != e {
		log.Print(e.Error())
		return
	}
	resp.Data = nil
	resp.Msg = "OK"
	resp.Status = 0
}

func GetDocTemplateId(c *gin.Context) {
	resp := RespBase{}
	defer func() {
		c.JSON(200, resp)
	}()
	sid := c.Param("id")
	id, e := strconv.Atoi(sid)
	if nil != e {
		log.Print(e.Error())
		return
	}
	ret, e := model.ReadDocTemplate(int32(id))
	if nil != e {
		log.Print(e.Error())
		return
	}
	if len(ret) > 0 {
		resp.Data = ret[0]
	} else {
		resp.Data = nil
	}
	resp.Msg = "OK"
	resp.Status = 0
}
